﻿' ******************************************************************************
' ** 
' **  Yahoo Finance Managed
' **  Written by Marius Häusler 2010
' **  It would be pleasant, if you contact me when you are using this code.
' **  Contact: YahooFinanceManaged@gmail.com
' **  Project Home: http://code.google.com/p/yahoo-finance-managed/
' **  
' ******************************************************************************
' **  
' **  Copyright 2010 Marius Häusler
' **  
' **  Licensed under the Apache License, Version 2.0 (the "License");
' **  you may not use this file except in compliance with the License.
' **  You may obtain a copy of the License at
' **  
' **    http://www.apache.org/licenses/LICENSE-2.0
' **  
' **  Unless required by applicable law or agreed to in writing, software
' **  distributed under the License is distributed on an "AS IS" BASIS,
' **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' **  See the License for the specific language governing permissions and
' **  limitations under the License.
' ** 
' ******************************************************************************

Imports System.Configuration
Namespace Finance.Support

    ''' <summary>
    ''' Stores default world market informations
    ''' </summary>
    ''' <remarks></remarks>
    Public Class WorldMarket
        Private Shared ReadOnly mHelper As New MyHelper
     
        Private Shared mCurrencies() As CurrencyInfo
        Private Shared mCountries() As CountryInfo
        Private Shared mContinents() As ContinentInfo
        Private Shared mStockExchanges As List(Of StockExchange)

        ''' <summary>
        ''' All available currencies.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared ReadOnly Property DefaultCurrencies() As CurrencyInfo()
            Get
                Return mCurrencies
            End Get
        End Property
        ''' <summary>
        ''' The CurrencyInfo object for specific Currency.
        ''' </summary>
        ''' <param name="cur"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared ReadOnly Property DefaultCurrencies(ByVal cur As Currency) As CurrencyInfo
            Get
                Return mCurrencies(CInt(cur))
            End Get
        End Property

        Public Shared ReadOnly Property DefaultCountries() As CountryInfo()
            Get
                Return mCountries
            End Get
        End Property
        Public Shared ReadOnly Property DefaultCountries(ByVal cnt As Country) As CountryInfo
            Get
                Return mCountries(CInt(cnt))
            End Get
        End Property


        ''' <summary>
        ''' The default stock exchanges. Is a reference for getting informations by setting the id of StockExchange or YahooID.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Property DefaultStockExchanges() As List(Of StockExchange)
            Get
                Return mStockExchanges
            End Get
            Set(ByVal value As List(Of StockExchange))
                If value IsNot Nothing Then mStockExchanges = value
            End Set
        End Property

        ''' <summary>
        ''' A list of all available continents
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Property AllFinanceContinents() As ContinentInfo()
            Get
                Return mContinents
            End Get
            Set(ByVal value As ContinentInfo())
                mContinents = value
            End Set
        End Property
        ''' <summary>
        ''' A list of all available countries
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared ReadOnly Property AllFinanceCountries() As CountryInfo()
            Get
                Dim lst As New List(Of CountryInfo)
                For Each reg As ContinentInfo In mContinents
                    lst.AddRange(reg.Countries)
                Next
                Return lst.ToArray
            End Get
        End Property
        ''' <summary>
        ''' A list of all available indices
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared ReadOnly Property AllFinanceIndices() As YIndexID()
            Get
                Dim lst As New List(Of Support.YIndexID)
                For Each cnt As CountryInfo In AllFinanceCountries
                    lst.AddRange(cnt.Indices)
                Next
                Return lst.ToArray
            End Get
        End Property


        Shared Sub New()
            mCurrencies = GetDefaultCurrencies()
            mCountries = GetDefaultCountries()
            mStockExchanges = New List(Of StockExchange)(GetDefaultStockExchanges())
            mContinents = GetDefaultWorldMarket()
        End Sub



        Public Class Worker
            Public Shared Sub Start()
                For i As Server = 0 To Server.YQL
                    WriteEnum(i.ToString, CInt(i))
                Next
            End Sub
            Public Shared Sub WriteEnum(ByVal en As String, ByVal i As Integer, Optional ByVal desc As String = "")

                Debug.WriteLine("''' <summary>")
                Debug.WriteLine("''' " & IIf(desc <> String.Empty, desc, en).ToString)
                Debug.WriteLine("''' </summary>")
                Debug.WriteLine("''' <remarks></remarks>")
                Debug.WriteLine(en & " = " & i.ToString)
                Debug.WriteLine("")

            End Sub
        End Class


        ''' <summary>
        ''' Loads a list of default currencies from market.xml
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function GetDefaultCurrencies() As CurrencyInfo()
            Dim currencies(CInt(Currency.ZWD)) As CurrencyInfo
            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml(My.Resources.market)
            Dim curs = xmlDoc.SelectNodes("//Resources/Currencies/Currency")

            If curs IsNot Nothing AndAlso curs.Count > 0 Then
                For cur As Currency = 0 To Currency.ZWD
                    For Each curNode As XmlNode In curs
                        Dim id As String = curNode.Attributes("ID").Value
                        If cur.ToString = id Then
                            Dim ci As New CurrencyInfo
                            ci.ID = cur
                            ci.Description = curNode.Attributes("Desc").Value
                            currencies(CInt(cur)) = ci
                            Exit For
                        End If
                    Next curNode
                Next cur
            End If

            Return currencies
        End Function
        Public Shared Function GetDefaultCountries() As CountryInfo()
            Dim countries(CInt(Country.VN)) As CountryInfo

            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml(My.Resources.market)
            Dim cntNodes = xmlDoc.SelectNodes("//Resources/Countries/Country")

            If cntNodes IsNot Nothing AndAlso cntNodes.Count > 0 Then
                Dim curID As String = String.Empty
                For Each cntNode As XmlNode In cntNodes
                    For cnt As Country = 0 To Country.VN
                        If cnt.ToString = cntNode.Attributes("ID").Value Then
                            Dim cntCur As Currency = Currency.AED
                            curID = cntNode.Attributes("Currency").Value
                            For Each cur As CurrencyInfo In DefaultCurrencies
                                If cur.ID.ToString = curID Then
                                    cntCur = cur.ID
                                    Exit For
                                End If
                            Next cur
                            countries(CInt(cnt)) = New CountryInfo(cnt, cntCur, cntNode.Attributes("Name").Value)
                            Exit For
                        End If
                    Next cnt
                Next cntNode
            End If

            Return countries
        End Function
        ''' <summary>
        ''' Loads a list of default stock exchanges from market.xml
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function GetDefaultStockExchanges() As StockExchange()
            Dim lst As New List(Of StockExchange)

            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml(My.Resources.market)
            Dim exchanges = xmlDoc.SelectNodes("//Resources/StockExchanges/StockExchange")

            If exchanges IsNot Nothing AndAlso exchanges.Count > 0 Then
                For Each exchangeNode As XmlNode In exchanges
                    Dim suffix As String = exchangeNode.Attributes("Suffix").Value
                    Dim id As String = exchangeNode.Attributes("ID").Value

                    Dim se As New StockExchange(id, suffix)

                    se.Name = exchangeNode.Attributes("Name").Value
                    se.DelayMinutes = Convert.ToInt32(exchangeNode.Attributes("DelayMinutes").Value)
                    se.RelativeToUTC = Convert.ToInt32(exchangeNode.Attributes("RelativeHoursToUTC").Value)
                    se.OpeningTimeUTC = Convert.ToDateTime(exchangeNode.Attributes("OpeningTimeUTC").Value)
                    se.ClosingTimeUTC = Convert.ToDateTime(exchangeNode.Attributes("ClosingTimeUTC").Value)

                    Dim curID As String = exchangeNode.Attributes("Currency").Value
                    For cur As Currency = 0 To Currency.ZWD
                        If cur.ToString = curID Then
                            se.Currency = cur
                            Exit For
                        End If
                    Next cur

                    Dim ctrID As String = exchangeNode.Attributes("Country").Value
                    For ctr As Country = 0 To Country.VN
                        If ctr.ToString = ctrID Then
                            se.Country = ctr
                            Exit For
                        End If
                    Next ctr

                    Dim trdDays As String = exchangeNode.Attributes("TradingDays").Value
                    se.TradingDays.Clear()
                    For Each day As String In trdDays.Split(","c)
                        Select Case day
                            Case "Mo" : se.TradingDays.Add(DayOfWeek.Monday)
                            Case "Tu" : se.TradingDays.Add(DayOfWeek.Tuesday)
                            Case "We" : se.TradingDays.Add(DayOfWeek.Wednesday)
                            Case "Th" : se.TradingDays.Add(DayOfWeek.Thursday)
                            Case "Fr" : se.TradingDays.Add(DayOfWeek.Friday)
                            Case "Sa" : se.TradingDays.Add(DayOfWeek.Saturday)
                            Case "Su" : se.TradingDays.Add(DayOfWeek.Sunday)
                        End Select
                    Next day

                    lst.Add(se)
                Next exchangeNode

            End If

            Return lst.ToArray
        End Function
        ''' <summary>
        ''' Loads default market information from market.xml
        ''' </summary>
        ''' <remarks></remarks>
        Public Shared Function GetDefaultWorldMarket() As ContinentInfo()
            Dim contList As New List(Of ContinentInfo)

            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml(My.Resources.market)
            Dim continents = xmlDoc.SelectNodes("//Resources/WorldMarket/Continent")

            If continents IsNot Nothing AndAlso continents.Count > 0 Then
                For Each continentNode As XmlNode In continents
                    Dim contName As String = continentNode.Attributes("Name").Value
                    Dim countries As New List(Of CountryInfo)
                    For Each countryNode As XmlNode In continentNode.ChildNodes
                        If countryNode.Name = "Country" Then
                            Dim ctrID As Country = Country.US
                            Dim ctrCur As Currency = Currency.USD
                            Dim ctrName As String = String.Empty
                            Dim indices As New List(Of YIndexID)

                            Dim ctrIDStr As String = countryNode.Attributes("ID").InnerText
                            For Each ctrInfo As CountryInfo In DefaultCountries
                                If ctrInfo.ID.ToString = ctrIDStr Then
                                    ctrID = ctrInfo.ID
                                    ctrCur = ctrInfo.Currency
                                    ctrName = ctrInfo.Name
                                    Exit For
                                End If
                            Next

                            For Each indexNode As XmlNode In countryNode.ChildNodes
                                If indexNode.Name = "Index" Then
                                    Dim name As String = indexNode.Attributes("Name").InnerText
                                    Dim id As String = indexNode.Attributes("ID").InnerText
                                    Dim seStr As String = indexNode.Attributes("StockExchange").InnerText
                                    Dim se As StockExchange = Nothing
                                    For Each exc As StockExchange In mStockExchanges
                                        If exc.ID = seStr Then
                                            se = New StockExchange(exc)
                                            Exit For
                                        End If
                                    Next
                                    Dim i As New YIndexID With {.Name = name, .StockExchange = se}
                                    i.SetID(id)
                                    indices.Add(i)
                                End If
                            Next indexNode

                            countries.Add(New CountryInfo(ctrID, ctrCur, ctrName, indices.ToArray))
                        End If
                    Next countryNode

                    contList.Add(New ContinentInfo(contName, countries.ToArray))
                Next continentNode

            End If

            Return contList.ToArray
        End Function


        ''' <summary>
        '''  Tries to return a StockExchange by StockExchange ID string
        ''' </summary>
        ''' <param name="id"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function GetStockExchangeByID(ByVal id As String) As StockExchange
            If WorldMarket.DefaultStockExchanges IsNot Nothing Then
                Dim n As String = id.ToUpper
                For Each se As StockExchange In WorldMarket.DefaultStockExchanges()
                    If se.ID = id Then
                        Return New StockExchange(se)
                    End If
                Next
            End If
            Return Nothing
        End Function
        ''' <summary>
        ''' Tries to return a StockExchange by an YID String
        ''' </summary>
        ''' <param name="suffix">e.g. "BAS.DE" or ".DE"</param>
        ''' <returns>The confirmed stock exchange or null</returns>
        ''' <remarks></remarks>
        Public Shared Function GetStockExchangeBySuffix(ByVal suffix As String) As StockExchange
            If WorldMarket.DefaultStockExchanges IsNot Nothing And suffix.Trim <> String.Empty Then
                Dim index As Integer = suffix.LastIndexOf("."c)
                If index >= 0 And suffix.Length >= index Then
                    Dim suffStr As String = suffix.Substring(index, suffix.Length - index).ToUpper
                    For Each se As StockExchange In WorldMarket.DefaultStockExchanges()
                        If se.Suffix = suffStr Then Return New StockExchange(se)
                    Next
                End If
            End If
            Return Nothing
        End Function
        ''' <summary>
        ''' Tries to return a StockExchange by the StockExchange's name
        ''' </summary>
        ''' <param name="name"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function GetStockExchangeByName(ByVal name As String) As StockExchange
            If WorldMarket.DefaultStockExchanges IsNot Nothing Then
                Dim n As String = name.ToLower
                If n = "stock" Then n = "nasdaq"
                For Each se As StockExchange In WorldMarket.DefaultStockExchanges()
                    If se.Name.ToLower.IndexOf(n) > -1 Then Return New StockExchange(se)
                Next
            End If
            Return Nothing
        End Function


    End Class

End Namespace